package com.zyj.benchmark.sample;

import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

import java.util.concurrent.TimeUnit;

/**
 * @Setup(Level.Trial)   整个多轮基准测试执行一次
 * @Setup(Level.Iteration)  每轮基准测试执行一次
 * @Setup(Level.Invocation)   每次调用基准测试方法都执行一次
 * --- 下面同理
 * @TearDown(Level.Trial)
 * @TearDown(Level.Iteration)
 * @TearDown(Level.Invocation)
 */
@Warmup(iterations = 1, time = 1, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 3, time = 1, timeUnit = TimeUnit.SECONDS)
@State(Scope.Thread)
public class Sample_06_FixtureLevel {

    double x;

    /**
     * Level.Trial: before or after the entire benchmark run (the sequence of iterations)
     * Level.Iteration: before or after the benchmark iteration (the sequence of invocations)
     * Level.Invocation; before or after the benchmark method invocation (WARNING: read the Javadoc before using)
     */
//    @Setup(Level.Trial) //与@TearDown同理
//    @TearDown(Level.Trial)//整个完整的基准测试完成之后才会执行一次
//    @TearDown(Level.Iteration)//每轮循环完成之后才会执行一次
    @TearDown(Level.Invocation)//每次方法被调用, 都会执行一次
    public void check() {
        assert x > Math.PI : "Nothing changed?";
    }

    @Benchmark
    public void measureRight() {
        x++;
    }

    @Benchmark
    public void measureWrong() throws InterruptedException {
        double x = 0;
        x++;
    }


    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(Sample_06_FixtureLevel.class.getSimpleName())
                .forks(1)
                .jvmArgs("-ea")

                //默认就是false, 即使 assert 错误也不会让整个测试失败
                //如果这里设置为true, assert 失败,就会让整个测试失败
                .shouldFailOnError(false) // switch to "true" to fail the complete run
                .build();

        new Runner(opt).run();
    }
}